﻿/*****************************************************************************
 
 Use of Ext is under the Ext JS license, for more information, 
 please visit http://extjs.com/products/license.php page. 
  
 You should confirm that you have read, understood and accept ethical criteria listed. 
 If not, see <http://www.mvcnext.com/license/>.
  
 Version: 1.0.0.0
 Website: http://www.mvcnext.com/
 Copyright (c) Yoganand R. All rights reserved.
 For continued development and updates, visit http://yogsbreath.net
 
 ******************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Reflection;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace MVCnExt.Web.UI.Ext
{
    /// <summary>
    /// The TreePanel provides tree-structured UI representation of tree-structured data.
    /// </summary>
    [Description("The TreePanel provides tree-structured UI representation of tree-structured data.")]
    public class ExtTreePanel : ExtComponent
    {
        private List<ScriptReference> _references = new List<ScriptReference>();

        public override List<ScriptReference> GetScriptReferences()
        {
            return base.GetScriptReferences();
        }

        public override IList<ScriptDescriptor> GetScriptDescriptors()
        {

            IList<ScriptDescriptor> list = base.GetScriptDescriptors();

            ScriptControlDescriptorBase desc = (ScriptControlDescriptorBase)list[0];

            desc.Type = "Ext.tree.TreePanel";

            String[] properties = new String[]{
                "animate", "containerScroll", "ddAppendOnly", "ddGroup", "ddScroll", "enableDD", "enableDrag", "enableDrop",
                "highlightColor", "highlightDrop", "lines", "pathSeparator", "rootVisible", "singleExpand", "border", "autoScroll", "ID"
            };

            Type component = typeof(ExtTreePanel);

            foreach (String property in properties)
            {
                PropertyInfo i = component.GetProperty(property);

                if (i == null)
                    throw new InvalidOperationException(String.Format("Property not found, 'ExtTreePanel.{0}'", property));

                Object value = i.GetValue(this, null);

                //get the default value
                if (value == null)
                {
                    // Gets the attributes for the property.
                    System.ComponentModel.AttributeCollection attributes =
                       TypeDescriptor.GetProperties(this)[property].Attributes;

                    /* get the default value by retrieving the DefaultValueAttribute 
                       from the AttributeCollection. */
                    DefaultValueAttribute defaultAttribute =
                       (DefaultValueAttribute)attributes[typeof(DefaultValueAttribute)];
                    if (defaultAttribute != null)
                        value = defaultAttribute.Value;
                }

                if (value == null)
                {
                    continue;
                }
                
                if (!(value is String))
                    desc.AddPropertyBase(property, value);
                else
                    desc.AddPropertyBase(property == "ID" ? property.ToLower() : property, String.Format("'{0}'", value));
            }

            //add nodes
            if (root != null)
            {
                // build tree
                StringBuilder rootNode = new StringBuilder("");

                for (int i = 0; i < root.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        rootNode.Append(",");
#if DEBUG
                        rootNode.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = root[i].GetScriptDescriptors();

                    // get the items's list of script dependencies
                    List<ScriptReference> references = root[i].GetScriptReferences();

                    // make sue the scrript dependencies are registered
                    _references.AddRange(references);

                    // write the item's config to the list
                    rootNode.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.NewOnly));
                }

                rootNode.Append("");

                desc.AddPropertyBase("root", rootNode);
            }

            //add nodes
            if (loader != null)
            {
                // build tree
                StringBuilder treeLoader = new StringBuilder("");

                for (int i = 0; i < loader.Count; i++)
                {
                    // add comma between items
                    if (i != 0)
                    {
                        treeLoader.Append(",");
#if DEBUG
                        treeLoader.AppendLine("\t\t\t");
#endif
                    }

                    // get the item script
                    IList<ScriptDescriptor> descriptors = loader[i].GetScriptDescriptors();

                    // get the items's list of script dependencies
                    List<ScriptReference> references = loader[i].GetScriptReferences();

                    // make sue the scrript dependencies are registered
                    _references.AddRange(references);

                    // write the item's config to the list
                    treeLoader.Append(((ExtScriptControlDescriptor)descriptors[0]).WriteScript(ScriptType.NewOnly));
                }

                treeLoader.Append("");

                desc.AddPropertyBase("loader", treeLoader);
            }


            return list;
        }

        #region Public Properties

        /// <summary>
        /// The root node for the tree.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof(ExtTreeNode))]
        [TemplateInstance(TemplateInstance.Single)]
        [Description("The root node for the tree.")]
        public List<ExtTreeNode> root { get; set; }

        /// <summary>
        /// The loader for the tree.
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [TemplateContainer(typeof(ExtTreeLoader))]
        [TemplateInstance(TemplateInstance.Single)]
        [Description("The loader for the tree.")]
        public List<ExtTreeLoader> loader { get; set; }

        public Boolean? autoScroll { get; set; }

        public Boolean border { get; set; }

        [DefaultValue(true)]
        [Description("true to enable animated expand/collapse (defaults to the value of Ext.enableFx)")]
        public Boolean animate { get; set; }

        [Description("True to register this container with ScrollManager")]
        public Boolean? containerScroll { get; set; }

        [Description("True if the tree should only allow append drops (use for trees which are sorted)")]
        public Boolean? ddAppendOnly { get; set; }

        [DefaultValue("")]
        [Description("The DD group this TreePanel belongs to")]
        public Boolean? ddGroup { get; set; }

        [Description("True to enable body scrolling")]
        public Boolean? ddScroll { get; set; }

        [Description("True to enable drag and drop")]
        public Boolean? enableDD { get; set; }

        [Description("True to enable just drag")]
        public Boolean? enableDrag { get; set; }

        [Description("True to enable just drop")]
        public Boolean? enableDrop { get; set; }

        [DefaultValue("C3DAF9")]
        [Description("The color of the node highlight (defaults to C3DAF9)")]
        public String highlightColor { get; set; }

        [DefaultValue(true)]
        [Description("False to disable node highlight on drop (defaults to the value of Ext.enableFx)")]
        public Boolean? highlightDrop { get; set; }

        [DefaultValue(true)]
        [Description("False to disable tree lines (defaults to true)")]
        public Boolean lines { get; set; }

        [DefaultValue("/")]
        [Description("The token used to separate sub-paths in path strings (defaults to '/')")]
        public String pathSeparator { get; set; }

        [DefaultValue(true)]
        [Description("false to hide the root node (defaults to true)")]
        public Boolean rootVisible { get; set; }

        [Description("true if only 1 node per branch may be expanded")]
        public Boolean? singleExpand { get; set; }

        [DefaultValue(true)]
        [Description("False to disable mouse over highlighting")]
        public Boolean trackMouseOver { get; set; }

        [Description("True to use Vista-style arrows in the tree (defaults to false)")]
        public Boolean? useArrows { get; set; }        

        #endregion
    }
}
